package com.niit.utils;

import java.sql.*;
import java.util.ResourceBundle;

/**
 * JDBC 工具类
 * 提供数据库连接、资源释放、CRUD操作等功能
 */
public class JDBCUtils {
    // 数据库连接信息
    private static final String DRIVER;
    private static final String URL;
    private static final String USERNAME;
    private static final String PASSWORD;

    // 使用静态代码块加载配置信息
    static {
        DRIVER = "com.mysql.cj.jdbc.Driver";
        URL  = "jdbc:mysql://localhost:3306/bookstore?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true";
        USERNAME  = "root";
        PASSWORD  = "123456";
        try {
            // 加载数据库驱动
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("加载数据库驱动失败", e);
        }
    }

    /**
     * 获取数据库连接
     * @return Connection 数据库连接对象
     */
    public static Connection getConnection() {
        try {
            return DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("获取数据库连接失败", e);
        }
    }

    /**
     * 释放资源
     * @param conn 连接对象
     * @param stmt Statement对象
     * @param rs 结果集对象
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("释放数据库资源失败", e);
        }
    }

    /**
     * 释放资源(不带结果集)
     * @param conn 连接对象
     * @param stmt Statement对象
     */
    public static void close(Connection conn, Statement stmt) {
        close(conn, stmt, null);
    }

    /**
     * 执行更新操作(INSERT, UPDATE, DELETE)
     * @param sql SQL语句
     * @param params 参数数组
     * @return 受影响的行数
     */
    public static int executeUpdate(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstmt = null;

        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);

            // 设置参数
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                }
            }

            return pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("执行更新操作失败", e);
        } finally {
            close(conn, pstmt);
        }
    }

    /**
     * 执行查询操作
     * @param sql SQL语句
     * @param params 参数数组
     * @return 结果集
     */
    public static ResultSet executeQuery(String sql, Object... params) {
        Connection conn = getConnection();
        PreparedStatement pstmt = null;

        try {
            pstmt = conn.prepareStatement(sql);

            // 设置参数
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                }
            }

            return pstmt.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
            close(conn, pstmt);
            throw new RuntimeException("执行查询操作失败", e);
        }
        // 注意：这里不关闭连接，由调用者处理ResultSet后调用close方法
    }

    /**
     * 查询单个值(如COUNT, MAX等聚合函数)
     * @param sql SQL语句
     * @param params 参数数组
     * @return 查询结果
     */
    public static Object querySingleValue(String sql, Object... params) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            conn = getConnection();
            pstmt = conn.prepareStatement(sql);

            // 设置参数
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                }
            }

            rs = pstmt.executeQuery();
            if (rs.next()) {
                return rs.getObject(1);
            }
            return null;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("查询单个值失败", e);
        } finally {
            close(conn, pstmt, rs);
        }
    }

    /**
     * 开启事务
     * @param conn 数据库连接
     */
    public static void beginTransaction(Connection conn) {
        try {
            if (conn != null) {
                conn.setAutoCommit(false);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("开启事务失败", e);
        }
    }

    /**
     * 提交事务
     * @param conn 数据库连接
     */
    public static void commitTransaction(Connection conn) {
        try {
            if (conn != null) {
                conn.commit();
                conn.setAutoCommit(true);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("提交事务失败", e);
        }
    }

    /**
     * 回滚事务
     * @param conn 数据库连接
     */
    public static void rollbackTransaction(Connection conn) {
        try {
            if (conn != null) {
                conn.rollback();
                conn.setAutoCommit(true);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException("回滚事务失败", e);
        }
    }
}